package com.pf.export;

import com.google.common.collect.Lists;
import com.pf.utils.ExportExcelUtils;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;
import org.apache.poi.xssf.usermodel.XSSFCell;
import org.apache.poi.xssf.usermodel.XSSFRow;
import org.apache.poi.xssf.usermodel.XSSFSheet;
import org.apache.poi.xssf.usermodel.XSSFWorkbook;

import java.io.FileOutputStream;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

/**
 * 级联下拉列表
 * <p>
 * 案例说明：
 * 本案例主要是实现excel下拉列表联动的效果，有以下几点需要注意说明：
 * 1.如果要实现excel下拉列表联动的效果，需使用excel中的名称管理器，如果是三级联动，需要将第一级和第二级下拉选项值放在名称管理器中。
 * 但名称管理器有一些限制，如名称不能重复，不能含有一些特殊符号（如（）@，等等）
 * <p>
 * 本案例生成的excel中，名称管理器名称没有重复。如上海，省字段值存储了【上海】，市字段值存储了【上海市】，所以不会重复，
 * 本案例也没考虑名称管理器名称含有特殊符号的场景，所以案例中调用 ExportExcelUtils.createSheetNameManger() 和 ExportExcelUtils.createCascadeDropDownList()方法时，isSpecialSymbolsHandle参数值都传了false。
 * <p>
 * 改进：
 * 如果需求中三级下拉级联，前面两级选项中有特殊符号或第二级选项中存在同名的选项（同名二级下拉所属的一级下拉肯定是不一样的），需要如何处理呢？
 * 请查看 CascadeDropDownListDemo_Plus 案例
 *
 * @author PanFei
 * @version 1.0.0
 * @createTime 2023/3/4 20:29
 */
public class CascadeDropDownListDemo {

    @Data
    @NoArgsConstructor
    @AllArgsConstructor
    public static class Address {
        private String province;
        private String city;
        private String area;
    }

    public static void main(String[] args) throws Exception {
        // 创建excel下拉级联
        createCascadeDropDownList();
    }

    /**
     * 创建省市区三级联动下拉列表
     */
    private static void createCascadeDropDownList() throws Exception {
        List<String> headTitles = Lists.newArrayList("省", "市", "区");
        XSSFWorkbook workbook = new XSSFWorkbook();
        String sheetName = "地址信息";
        XSSFSheet sheet = workbook.createSheet(sheetName);
        // 创建表头
        int rowIndex = 0;
        XSSFRow headRow = sheet.createRow(rowIndex);
        for (int i = 0; i < headTitles.size(); i++) {
            XSSFCell headCell = headRow.createCell(i);
            headCell.setCellValue(headTitles.get(i));
        }

        // 数据行显示级联下拉
        List<Address> dataList = getExcelData();
        for (int i = 0; i < dataList.size(); i++) {
            rowIndex = rowIndex + 1;
            XSSFRow dataRow = sheet.createRow(rowIndex);
            Address address = dataList.get(i);
            XSSFCell provinceCell = dataRow.createCell(0);
            provinceCell.setCellValue(address.getProvince());

            XSSFCell cityCell = dataRow.createCell(1);
            cityCell.setCellValue(address.getCity());

            XSSFCell areaCell = dataRow.createCell(2);
            areaCell.setCellValue(address.getArea());
        }

        // 为省市区显示级联下拉选项
        List<String> provinceOptionList = getProvinceList();
        // 1.先为省设置下拉选项
        ExportExcelUtils.createUnlimitedDropDownList(workbook, sheetName, 0, 0, provinceOptionList);


        // 2.为市，区设置联动下拉
        // 2.1.先生成excel名称管理器
        Map<String, List<String>> targetMap = getAddressMap();
        ExportExcelUtils.createSheetNameManger(workbook, 1, targetMap, false);
        // 2.2.为市，区设置联动下拉
        ExportExcelUtils.createCascadeDropDownList(workbook, sheetName, 1, "$A2", false);
        ExportExcelUtils.createCascadeDropDownList(workbook, sheetName, 2, "$B2", false);

        // 3.输出账单excel
        workbook.write(new FileOutputStream("D:/test/provinceCityArea.xlsx"));
        System.out.println(">>>> 导出成功...");
    }

    /**
     * 省列下拉选项值
     *
     * @return
     */
    private static List<String> getProvinceList() {
        return Lists.newArrayList("陕西省", "上海", "四川省");
    }

    /**
     * 模拟的三级联动下拉选项信息
     * <p>
     * 三级下拉中第一级和第二级下拉选项值需要存储在excel的名称管理器中
     * 该map集合中的key将来就是excel名称管理器中各组数据的名称，值就是对应隐藏sheet页的指定行列数据（excel名称管理器的名称是不能重复）
     *
     * @return
     */
    private static Map<String, List<String>> getAddressMap() {
        /**
         * 陕西省  西安市  雁塔区
         * 陕西省  西安市  长安区
         * 陕西省  宝鸡市  眉县
         * 陕西省  宝鸡市  岐山县
         * 上海   上海市  黄埔区
         * 上海   上海市  静安区
         * 四川省  成都市  金牛区
         * 四川省  成都市  锦江区
         * 四川省  自贡市  自流井区
         * 四川省  自贡市  富顺县
         */

        Map<String, List<String>> map = new HashMap<>();
        map.put("陕西省", Lists.newArrayList("西安市", "宝鸡市"));
        map.put("上海", Lists.newArrayList("上海市"));
        map.put("四川省", Lists.newArrayList("成都市", "自贡市"));
        map.put("西安市", Lists.newArrayList("雁塔区", "长安区"));
        map.put("宝鸡市", Lists.newArrayList("眉县", "岐山县"));
        map.put("上海市", Lists.newArrayList("黄埔区", "静安区"));
        map.put("成都市", Lists.newArrayList("金牛区", "锦江区"));
        map.put("自贡市", Lists.newArrayList("自流井区", "富顺县"));
        return map;
    }

    /**
     * excel列表显示的数据行信息
     *
     * @return
     */
    private static List<Address> getExcelData() {
        Address a1 = new Address("陕西省", "西安市", "雁塔区");
        Address a2 = new Address("上海", "上海市", "黄埔区");
        Address a3 = new Address("四川省", "成都市", "金牛区");
        return Lists.newArrayList(a1, a2, a3);
    }
}
